package com.juren;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;

/**
 * @ClassName 网关
 * @Description
 * @Author zhangtao
 * @Date 2019/4/23 18:01
 * @Version 1.0
 **/
@SpringBootApplication
@RestController
public class GatewayApp {
    public static void main(String[] args) {
        SpringApplication.run(GatewayApp.class, args);
    }

    /**
     * @Author zhangtao
     * @Description
     * <p>
     *     使用了一个RouteLocatorBuilder的bean去创建路由，
     *     除了创建路由RouteLocatorBuilder可以让你添加各种predicates和filters，
     *     predicates断言的意思，顾名思义就是根据具体的请求的规则，
     *     由具体的route去处理，filters是各种过滤器，用来对请求做各种判断和修改。
     *     创建的route可以让请求“/get”请求都转发到“http://httpbin.org/get”。
     *     在route配置上，我们添加了一个filter，该filter会将请求添加一个header,key为hello，value为world。
     * </p>
     * @Date  2019/5/31 9:45
     * @Param [builder]
     * @return org.springframework.cloud.gateway.route.RouteLocator
     */
    /*@Bean
    public RouteLocator myRoutes(RouteLocatorBuilder builder) {
        return builder.routes()
                .route(p -> p
                        .path("/get")
                        .filters(f -> f.addRequestHeader("Hello", "World"))
                        .uri("http://httpbin.org:80"))
                .build();
    }*/


    /**
     * @Author zhangtao
     * @Description
     * <p>
     *  比上例子多添加了Hystrix熔断
     *  在上面的代码中，我们使用了另外一个router，
     *  该router使用host去断言请求是否进入该路由，
     *  当请求的host有“*.hystrix.com”，都会进入该router，
     *  该router中有一个hystrix的filter,该filter可以配置名称、和指向性fallback的逻辑的地址，比如本案例中重定向到了“/fallback”。
     * </p>
     * @Date  2019/5/31 9:54
     * @Param [builder]
     * @return org.springframework.cloud.gateway.route.RouteLocator
     */
    @Bean
    public RouteLocator myRoutes(RouteLocatorBuilder builder) {
        String httpUri = "http://httpbin.org:80";
        return builder.routes()
                .route(p -> p
                        .path("/get")
                        .filters(f -> f.addRequestHeader("Hello", "World"))
                        .uri(httpUri))
                .route(p -> p
                        .host("*.hystrix.com")
                        .filters(f -> f
                                .hystrix(config -> config
                                        .setName("mycmd")
                                        .setFallbackUri("forward:/fallback")))
                        .uri(httpUri))
                .build();
    }

    /**
     * @ClassName FallbackController
     * @Description
     * <p>
     *     “/fallback”的逻辑
     *     Mono是一个Reactive stream，对外输出一个“fallback”字符串。
     *     在windows在使用curl(cmd命令行即可) 执行如下命令
     *     curl --dump-header - --header Host:www.hystrix.com http://localhost:8080/delay/3
     *     curl命令安装---->https://www.cnblogs.com/xing901022/p/4652624.html
     *     带host  www.hystrix.com的请求执行了hystrix的fallback的逻辑。
     * </p>
     * @Author zhangtao
     * @Date 2019/5/31 10:01
     * @Version 1.0
     **/
    public Mono<String> fallback(){
        return Mono.just("fallback");
    }

}
